home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d4 / Telnet2.6.1d4.src.sit.hqx / Telnet 2.6.1d4 source / source / config / configure.c next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  36.2 KB  |  1,160 lines

  1. /*    Configure.c
  2. *    New Configuration scheme (the death of config.tel)
  3. *
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1993,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. *****************************************************************
  16. *  Revisions:
  17. *  8/92        Telnet 2.6:    Initial version.  Jim Browne
  18. */
  19.  
  20. #ifdef MPW
  21. #pragma segment Configure
  22. #endif
  23.  
  24. #include "TelnetHeader.h"
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <Picker.h>
  29.  
  30. #include "newresrc.h"
  31.  
  32. #include "DlogUtils.proto.h"
  33. #include "popup.h"
  34. #include "popup.proto.h"
  35. #include "configure.proto.h"
  36. #include "netevent.proto.h"        /* For Stask proto */
  37. #include "prefs.proto.h"
  38. #include "bkgr.proto.h"            // For StartUpFTP proto
  39. #include "menuseg.proto.h"
  40. #include "macutil.proto.h"        
  41.  
  42. static    pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item);
  43. PROTO_UPP(TerminalModalProc, ModalFilter);
  44. static    pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item);
  45. PROTO_UPP(SessionModalProc, ModalFilter);
  46. static    pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item);
  47. PROTO_UPP(MyDlogWListFilter, ModalFilter);
  48.  
  49. static    pascal void    listDitemproc(DialogPtr theDlg, short itemNo);
  50. PROTO_UPP(listDitemproc, UserItem);
  51.  
  52. extern SysEnvRec theWorld;        /* BYU 2.4.18 - System Environment record */
  53. extern    FTPServerPrefs*        gFTPServerPrefs;
  54. extern    ApplicationPrefs*    gApplicationPrefs;
  55.  
  56. static    void ZeroNumOnly(void);
  57. static    Boolean InNumOnly(short item);
  58.  
  59. #define NUMONLYSIZE 8
  60. short NumOnly[NUMONLYSIZE];        /* Items for which non-number keys are ignored */
  61.                                 // NumOnly[0] is number of "safe" item to return
  62.  
  63. void    CONFIGUREunload(void) {}
  64.                         
  65. void Cenviron( void)
  66. {
  67.     DialogPtr    dptr;
  68.     short         ditem;
  69.     Str255        scratchPstring;
  70.     long         scratchlong;
  71.     OSType        newtype;
  72.     
  73.     dptr = GetNewMySmallStrangeDialog( PrefDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  74.     
  75.     SetCntrl(dptr, PrefDClose, gApplicationPrefs->WindowsDontGoAway);
  76.     SetCntrl(dptr, PrefStag, gApplicationPrefs->StaggerWindows);
  77.     SetCntrl(dptr, PrefCMDkey, gApplicationPrefs->CommandKeys);
  78.     SetCntrl(dptr, PrefTMap, gApplicationPrefs->RemapTilde);
  79.     SetCntrl(dptr, PrefBlink, gApplicationPrefs->BlinkCursor);
  80.     SetCntrl(dptr, PrefKeyFuncMenus, gApplicationPrefs->KeyPadAndFuncMenus);
  81.  
  82.     SetCntrl(dptr, PrefBlockCursor, (gApplicationPrefs->CursorType == 0));
  83.     SetCntrl(dptr, PrefUnderscoreCursor, (gApplicationPrefs->CursorType == 1));
  84.     SetCntrl(dptr, PrefVerticalCursor, (gApplicationPrefs->CursorType == 2));
  85.  
  86.     scratchPstring[0] = 4;
  87.     BlockMove(&(gApplicationPrefs->CaptureFileCreator), &scratchPstring[1], sizeof(OSType));
  88.     SetTEText(dptr, PrefCaptTE, scratchPstring);
  89.     newtype = gApplicationPrefs->CaptureFileCreator;
  90.  
  91.     scratchlong = gApplicationPrefs->CopyTableThresh;
  92.     NumToString(scratchlong, scratchPstring);
  93.     SetTEText(dptr, PrefCTt, scratchPstring);
  94.     SelIText(dptr, PrefCTt, 0, 32767);
  95.  
  96.     NumToString(gApplicationPrefs->TimeSlice, scratchPstring);
  97.     SetTEText(dptr, PrefTimeSlice, scratchPstring);
  98.  
  99.     ShowWindow(dptr);
  100.     ditem=0;                                /* initially no hits */
  101.     while((ditem>2) || (ditem==0)) {    
  102.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  103.         switch(ditem) {
  104.             case PrefDClose:
  105.             case PrefStag:
  106.             case PrefCMDkey:
  107.             case PrefTMap:
  108.             case PrefBlink:
  109.             case PrefKeyFuncMenus:
  110.                 FlipCheckBox( dptr, ditem);
  111.                 break;
  112.  
  113.             case PrefBlockCursor:
  114.                 SetCntrl(dptr, PrefBlockCursor, 1);
  115.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  116.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  117.                 break;
  118.             case PrefUnderscoreCursor:
  119.                 SetCntrl(dptr, PrefBlockCursor, 0);
  120.                 SetCntrl(dptr, PrefUnderscoreCursor, 1);
  121.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  122.                 break;
  123.             case PrefVerticalCursor:
  124.                 SetCntrl(dptr, PrefBlockCursor, 0);
  125.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  126.                 SetCntrl(dptr, PrefVerticalCursor, 1);
  127.                 break;
  128.  
  129.             case PrefCaptCreat:
  130.                 GetApplicationType(&newtype);
  131.                 scratchPstring[0] = 4;
  132.                 BlockMove(&newtype, &scratchPstring[1], sizeof(OSType));
  133.                 SetTEText(dptr, PrefCaptTE, scratchPstring);
  134.             default:
  135.                 break;
  136.             } /* switch */
  137.         }
  138.     
  139.     if (ditem==DLOGCancel) {
  140.             DisposDialog( dptr);
  141.             return;
  142.             }
  143.  
  144.     GetTEText(dptr, PrefCTt, scratchPstring);
  145.     StringToNum(scratchPstring, &scratchlong);
  146.     gApplicationPrefs->CopyTableThresh = (short) scratchlong;
  147.  
  148.     GetTEText(dptr, PrefTimeSlice, scratchPstring);
  149.     StringToNum(scratchPstring, &scratchlong);
  150.     BoundsCheck(&scratchlong, 100, 2);
  151.     gApplicationPrefs->TimeSlice = scratchlong;
  152.  
  153.     GetTEText(dptr, PrefCaptTE, scratchPstring);
  154.     BlockMove(&scratchPstring[1], &(gApplicationPrefs->CaptureFileCreator), sizeof(OSType));
  155.  
  156.     gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey);                    
  157.     gApplicationPrefs->WindowsDontGoAway = GetCntlVal(dptr, PrefDClose);
  158.     gApplicationPrefs->RemapTilde =    GetCntlVal(dptr, PrefTMap);
  159.     gApplicationPrefs->StaggerWindows = GetCntlVal(dptr, PrefStag);
  160.     gApplicationPrefs->BlinkCursor = GetCntlVal(dptr, PrefBlink);
  161.     gApplicationPrefs->KeyPadAndFuncMenus = GetCntlVal(dptr, PrefKeyFuncMenus);
  162.  
  163.     gApplicationPrefs->CursorType = (GetCntlVal(dptr, PrefUnderscoreCursor) == 1) + (2 *
  164.                                      (GetCntlVal(dptr, PrefVerticalCursor) == 1));
  165.                                      
  166.     switchMenus(gApplicationPrefs->CommandKeys);
  167.     SavePreferences();
  168.     
  169.     DisposDialog( dptr);
  170. }
  171.  
  172. void Cftp(void)
  173. {
  174.     DialogPtr            dptr;
  175.     short                ditem;
  176.     Str255                scratchPstring;
  177.     OSType                scratchOSType;
  178.     SFReply                sfr;
  179.     FInfo                fi;            
  180.     Point                where = {100,100};
  181.     
  182.     dptr = GetNewMySmallStrangeDialog( FTPDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  183.  
  184.     SetCntrl(dptr, FTPServerOff, (gFTPServerPrefs->ServerState == 0));
  185.     SetCntrl(dptr, FTPServerUnsecure, (gFTPServerPrefs->ServerState == 1));
  186.     SetCntrl(dptr, FTPServerPswdPlease, (gFTPServerPrefs->ServerState == 2));
  187.     SetCntrl(dptr, FTPShowFTPlog, gFTPServerPrefs->ShowFTPlog);
  188.     SetCntrl(dptr, FTPrevDNS, gFTPServerPrefs->DNSlookupconnections);
  189.     SetCntrl(dptr, FTPUseMacBinaryII, gFTPServerPrefs->UseMacBinaryII);
  190.     SetCntrl(dptr, FTPResetMacBinary, gFTPServerPrefs->ResetMacBinary);
  191.     SetCntrl(dptr, FTPISO, gFTPServerPrefs->DoISOtranslation);
  192.  
  193.     HideDItem(dptr, FTPrevDNS);        // Sometime later, perhaps.
  194.     
  195.     scratchPstring[0] = 4;
  196.  
  197.     BlockMove(&(gFTPServerPrefs->BinaryCreator), &scratchPstring[1], sizeof(OSType));
  198.     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  199.     
  200.     BlockMove(&(gFTPServerPrefs->BinaryType), &scratchPstring[1], sizeof(OSType));
  201.     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  202.     SelIText(dptr, FTPbintypeTE, 0, 32767);
  203.  
  204.     BlockMove(&(gFTPServerPrefs->TextCreator), &scratchPstring[1], sizeof(OSType));
  205.     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  206.  
  207.     ShowWindow(dptr);
  208.     ditem=0;                                    /* initially no hits */
  209.     while((ditem>2) || (ditem==0)) {    
  210.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  211.         switch(ditem) {
  212.             case    FTPShowFTPlog:
  213.             case    FTPrevDNS:
  214.             case    FTPUseMacBinaryII:
  215.             case    FTPResetMacBinary:
  216.             case    FTPISO:
  217.                 FlipCheckBox( dptr, ditem);
  218.                 break;
  219.  
  220.             case    FTPServerOff:
  221.                 SetCntrl(dptr, FTPServerOff, 1);
  222.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  223.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  224.                 break;
  225.             case    FTPServerUnsecure:
  226.                 SetCntrl(dptr, FTPServerOff, 0);
  227.                 SetCntrl(dptr, FTPServerUnsecure, 1);
  228.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  229.                 break;
  230.             case    FTPServerPswdPlease:
  231.                 SetCntrl(dptr, FTPServerOff, 0);
  232.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  233.                 SetCntrl(dptr, FTPServerPswdPlease, 1);
  234.                 break;
  235.  
  236.             case    FTPtextcreatorbutton:
  237.                 if (GetApplicationType(&scratchOSType)) {
  238.                     BlockMove(&scratchOSType, &scratchPstring[1], sizeof(OSType));
  239.                     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  240.                     }
  241.                 break;
  242.             
  243.             case    FTPbinexamplebutton:
  244.                 SFGetFile(where, NULL, NULL, -1, NULL, NULL, &sfr);
  245.                 if (sfr.good) {
  246.                     GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  247.                     scratchPstring[0] = sizeof(OSType);
  248.                     BlockMove(&fi.fdCreator, &scratchPstring[1], sizeof(OSType));
  249.                     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  250.                     BlockMove(&fi.fdType, &scratchPstring[1], sizeof(OSType));
  251.                     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  252.                     }
  253.                 break;    
  254.             default:
  255.                 break;
  256.             } /* switch */
  257.         } /* while */
  258.     
  259.     if (ditem==DLOGCancel) {
  260.             DisposDialog( dptr);
  261.             return;
  262.             }
  263.  
  264.     gFTPServerPrefs->ServerState = GetCntlVal(dptr, FTPServerUnsecure) + 
  265.         GetCntlVal(dptr, FTPServerPswdPlease) * 2;
  266.     StartUpFTP();            // Make sure FTP server recognizes new mode.
  267.     
  268.     gFTPServerPrefs->ShowFTPlog = GetCntlVal(dptr, FTPShowFTPlog);
  269.     gFTPServerPrefs->DNSlookupconnections = GetCntlVal(dptr, FTPrevDNS);
  270.     gFTPServerPrefs->UseMacBinaryII = GetCntlVal(dptr, FTPUseMacBinaryII);
  271.     gFTPServerPrefs->ResetMacBinary = GetCntlVal(dptr, FTPResetMacBinary);
  272.     gFTPServerPrefs->DoISOtranslation = GetCntlVal(dptr, FTPISO);
  273.  
  274.     GetTEText(dptr, FTPbincreatTE, scratchPstring);
  275.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryCreator), sizeof(OSType));
  276.     
  277.     GetTEText(dptr, FTPbintypeTE, scratchPstring);
  278.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryType), sizeof(OSType));
  279.  
  280.     GetTEText(dptr, FTPtextcreatTE, scratchPstring);
  281.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->TextCreator), sizeof(OSType));
  282.  
  283.     SavePreferences();
  284.     
  285.     DisposDialog( dptr);
  286. }
  287.  
  288. Boolean GetApplicationType(OSType *type)
  289. {
  290.     SFTypeList types;
  291.     SFReply sfr;
  292.     FInfo fi;
  293.     Point where;
  294.     
  295.     SetPt(&where, 100, 100);
  296.     types[0] = 'APPL';
  297.     SFGetFile(where, NULL, NULL, 1, types, NULL, &sfr);
  298.     if (sfr.good) {
  299.         GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  300.         BlockMove(&fi.fdCreator, type, sizeof(OSType));        // Copy the application creator type
  301.         }
  302.         
  303.     return(sfr.good);
  304. }
  305.  
  306. //    Our standard modal dialog filter with code for handling user items containing lists.
  307. SIMPLE_UPP(MyDlogWListFilter, ModalFilter);
  308. pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item)
  309. {
  310.     short keyCode, key, iType;
  311.     Handle iHndl;
  312.     Rect iRect;
  313.     Point scratchPoint;
  314.  
  315.     SetPort(dptr);
  316.     if (evt->what == keyDown) {
  317.         key = evt->message & charCodeMask;
  318.         keyCode = (evt->message >>8) & 0xff ;
  319.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  320.             *item = 1;                // ok
  321.             FlashButton(dptr, 1);
  322.             return(-1);
  323.             }
  324.         }
  325.     else if (evt->what == updateEvt) {
  326.         if ((WindowPtr)evt->message == dptr) {
  327.             GetDItem(dptr,1,&iType,&iHndl,&iRect);    // ok
  328.             PenSize(3,3);
  329.             InsetRect(&iRect,-4,-4);
  330.             FrameRoundRect(&iRect,16,16);
  331.             }
  332.     }
  333.     
  334.     if (evt->what == mouseDown) {
  335.         GetDItem(dptr, kItemList, &iType, &iHndl, &iRect);
  336.         scratchPoint = evt->where;
  337.         GlobalToLocal(&scratchPoint);
  338.         if (PtInRect(scratchPoint, &iRect)) {
  339.             *item = kItemList;
  340.             if (LClick(scratchPoint, evt->modifiers, (ListHandle)GetWRefCon(dptr))) {
  341.                 *item = kChange;
  342.                 FlashButton(dptr, kChange);
  343.                 }    
  344.             return(-1);
  345.         }
  346.     }
  347.     
  348.     return(FALSE);
  349. }
  350.  
  351. //    User Dialog Item Procedure for a list.  Assumes the Dialog's refcon contains the list
  352. //    handle.
  353. SIMPLE_UPP(listDitemproc, UserItem);
  354. pascal void    listDitemproc(DialogPtr theDlg, short itemNo)
  355. {
  356.     short        itemType;
  357.     Handle        ControlHndl;
  358.     Rect        scratchRect;
  359.     
  360.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  361.     
  362.     PenNormal();
  363.     InsetRect(&scratchRect, -1, -1);
  364.     FrameRect(&scratchRect);
  365.     LUpdate(theDlg->visRgn, (ListHandle)GetWRefCon(theDlg));
  366. }
  367.  
  368. void    BoundsCheck(long *value, long high, long low)
  369. {
  370.     if (*value > high) *value = high;
  371.     if (*value < low) *value = low;
  372. }
  373.  
  374. void    EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)(StringPtr))
  375. {
  376.     DialogPtr    dptr;
  377.     Handle         iHndl;
  378.     short         iType, length, ditem, numberofitems, index, resID;
  379.     Rect         ListBox, ListBounds;
  380.     Point         cellSize, theCell;
  381.     ListHandle    thelist;
  382.     Handle        ItemResource;
  383.     Str255        ItemName;
  384.     ResType        restype;
  385.  
  386.     dptr = GetNewMySmallDialog(kItemDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  387.     ditem = 3;
  388.  
  389.     GetDItem(dptr, kItemList, &iType, &iHndl, &ListBox);
  390.     SetDItem(dptr, kItemList, iType, (Handle)listDitemprocUPP, &ListBox);
  391.     
  392.  
  393.     ListBox.right -= 15;        // Make room for scrollbar
  394.     SetRect(&ListBounds, 0,0,1,0);
  395.     SetPt(&cellSize,(ListBox.right-ListBox.left),16);
  396.     thelist = LNew(&ListBox, &ListBounds, cellSize, 0, (WindowPtr)dptr,0,0,0,1);
  397. #define kSCListMods lNoNilHilite+lOnlyOne
  398.     (*(thelist))->listFlags = kSCListMods;
  399.     
  400.     SetWRefCon(dptr, (long)thelist);        // So the Ditem proc can find the list
  401.     
  402.     UseResFile(TelInfo->SettingsFile);
  403.     numberofitems = Count1Resources(ConfigResourceType);
  404.     
  405.     for(index = 1, theCell.v = 0, theCell.h = 0; index <= numberofitems;
  406.                  index++, theCell.v++) {
  407.         ItemResource = Get1IndResource(ConfigResourceType, index);
  408.         GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName);
  409.         LAddRow(1,-1, thelist);
  410.         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  411.         ReleaseResource(ItemResource);
  412.         }
  413.         
  414.     theCell.v = 0;
  415.     theCell.h = 0;
  416.     if (numberofitems) LSetSelect(1, theCell, thelist);
  417.     LDoDraw(1, thelist);
  418. //    LUpdate(dptr->visRgn, thelist); Is this needed?
  419.     
  420.     while (ditem > 1) {
  421.         ModalDialog(MyDlogWListFilterUPP, &ditem);
  422.         
  423.         switch(ditem) {
  424.             case kRemove:
  425.                 SetPt(&theCell, 0, 0);
  426.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  427.                     length = 254;
  428.                     LGetCell(ItemName+1, &length, theCell, thelist);
  429.                     ItemName[0] = (char)length;
  430.                     if (!(EqualString(ItemName, "\p<Default>", TRUE, FALSE))) {
  431.                         LDelRow(1,theCell.v,thelist);
  432.                         UseResFile(TelInfo->SettingsFile);
  433.                         ItemResource = Get1NamedResource(ConfigResourceType, ItemName);
  434.                         RmveResource(ItemResource);
  435.                         ReleaseResource(ItemResource);
  436.                         UpdateResFile(TelInfo->SettingsFile);
  437.                         }
  438.                     }
  439.             break;
  440.             
  441.             case kChange:
  442.                 SetPt(&theCell, 0, 0);
  443.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  444.                     length = 254;
  445.                     LGetCell(ItemName+1, &length, theCell, thelist);
  446.                     ItemName[0] = (char)length;
  447.                     if ((*EditFunction)((StringPtr)&ItemName)) {
  448.                         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  449.                     }
  450.                 }
  451.             break;
  452.             
  453.             case kNew:        
  454.                 ItemName[0] = 0;                    // Signal new shortcut
  455.                 if ((*EditFunction)((StringPtr)&ItemName)) {
  456.                     theCell.v = LAddRow(1, -1, thelist);
  457.                     LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  458.                 }
  459.             break;
  460.         } // switch
  461.         
  462.         SetPt(&theCell, 0, 0);
  463.         if (LGetSelect(TRUE, &theCell, thelist)) {
  464.             Hilite(dptr, kRemove, 0);
  465.             Hilite(dptr, kChange, 0);
  466.             }
  467.         else {
  468.             Hilite(dptr, kRemove, 255);
  469.             Hilite(dptr, kChange, 255);
  470.             }
  471.         
  472.     } // while
  473.     
  474.     LDispose(thelist);
  475.     DisposDialog(dptr);
  476. }
  477.  
  478. void ZeroNumOnly(void)
  479. {
  480.     short i;
  481.     
  482.     for(i=0; i<NUMONLYSIZE; i++) NumOnly[i]=0;
  483. }
  484.  
  485. Boolean InNumOnly(short item)
  486. {
  487.     short index = 1;
  488.     
  489.     while ((NumOnly[index] != item) && (NumOnly[index] != 0)) index++;
  490.     
  491.     return(NumOnly[index] == item);
  492. }
  493.  
  494. short        NumberOfColorBoxes;
  495. short        BoxColorItems[8];
  496. RGBColor    BoxColorData[8];
  497.  
  498. SIMPLE_UPP(ColorBoxItemProc, UserItem);
  499. pascal void    ColorBoxItemProc(DialogPtr theDlg, short itemNo)
  500. {
  501.     short        itemType, index = 0;
  502.     Handle        ControlHndl;
  503.     Rect        scratchRect;
  504.     RGBColor    rgb;
  505.  
  506.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  507.     PenNormal();
  508.     FrameRect(&scratchRect);
  509.     InsetRect(&scratchRect, 1, 1);            // Why isn't this framing the boxes?
  510.     
  511.     GetForeColor(&rgb);
  512.  
  513.     while ((index < NumberOfColorBoxes) && (BoxColorItems[index] != itemNo)) index++;
  514.     
  515.     RGBForeColor(&BoxColorData[index]);        /* color corresponding to item */
  516.     PaintRect(&scratchRect);
  517.  
  518.     RGBForeColor(&rgb);            /* restore previous foreground color */
  519. }
  520.  
  521. SIMPLE_UPP(ColorBoxModalProc, ModalFilter);
  522. pascal short ColorBoxModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  523. {
  524.     short keyCode, key, iType, index;
  525.     Handle    iHndl;
  526.     Rect    iRect;
  527.     
  528.     if ((evt->what == keyDown) || (evt->what == autoKey)) {
  529.         key = evt->message & charCodeMask;
  530.         keyCode = (evt->message >>8) & 0xff;
  531.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  532.             *item = DLOGOk;
  533.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  534.             }
  535.         if (((key == '.') && (evt->modifiers & cmdKey)) ||
  536.             ((key == 0x1b) && (keyCode == 0x35)) ) {    // 0x35 == escKey
  537.             *item = DLOGCancel;
  538.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  539.             }
  540.  
  541.         if ((key < '0' || key > '9') && 
  542.             !(key == 0x08 || key == 0x09 || (key > 0x1B && key < 0x20))
  543.             && InNumOnly(((DialogPeek)dptr)->editField + 1)) {
  544.                 /* Reject non-numbers for this TE */
  545.                 *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  546.                 return(-1);
  547.                 }   
  548.            }
  549.            
  550.     if (evt->what == updateEvt) {
  551.         if ((WindowPtr)evt->message == dptr) {
  552.             GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect);    // ok
  553.             PenSize(3,3);
  554.             InsetRect(&iRect,-4,-4);
  555.             FrameRoundRect(&iRect,16,16);
  556.             for (index = 0; index < NumberOfColorBoxes; index++)
  557.                 ColorBoxItemProc(dptr, BoxColorItems[index]);        // update color boxes
  558.             }
  559.     }
  560.     
  561.     Stask();
  562.     return(FALSE);
  563. }
  564.  
  565. SIMPLE_UPP(TerminalModalProc, ModalFilter);
  566. pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  567. {
  568.     if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item));
  569.  
  570.     return(ColorBoxModalProc(dptr, evt, item));
  571. }
  572.  
  573. SIMPLE_UPP(SessionModalProc, ModalFilter);
  574. pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item)
  575. {
  576.     if ((evt->what == keyDown) || (evt->what == autoKey))
  577.         if ((evt->message & charCodeMask) == ' ') {
  578.             *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  579.             return(-1);
  580.             }
  581.     
  582.     return(TerminalModalProc(dptr, evt, item));
  583. }
  584.  
  585. Boolean EditTerminal(StringPtr PrefRecordNamePtr)
  586. {
  587.     DialogPtr        dptr;
  588.     short            ditem, scratchshort, resourceID;
  589.     long            scratchlong;
  590.     ResType            scratchResType;
  591.     Boolean            IsNewPrefRecord, UserLikesNewColor;
  592.     TerminalPrefs**    TermPrefsHdl;
  593.     TerminalPrefs*    TermPrefsPtr;
  594.     Str255            scratchPstring;
  595.     RGBColor        scratchRGBcolor;
  596.     Point            ColorBoxPoint;
  597.     MenuHandle        WeNeedAFontMenuHandle;
  598.     popup TPopup[] = {{TermFontPopup, (MenuHandle) 0, 1},
  599.                         {0, (MenuHandle) 0, 0}};
  600.  
  601.     dptr = GetNewMySmallStrangeDialog(TermDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  602.     ditem = 3;
  603.     
  604.     WeNeedAFontMenuHandle = NewMenu(666, "\p");
  605.     AddResMenu(WeNeedAFontMenuHandle, 'FONT');
  606.     TPopup[0].h = WeNeedAFontMenuHandle;
  607.     PopupInit(dptr, TPopup);
  608.     
  609.     if (PrefRecordNamePtr[0] != 0) {
  610.         IsNewPrefRecord = FALSE;
  611.         UseResFile(TelInfo->SettingsFile);
  612.         TermPrefsHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, PrefRecordNamePtr);
  613.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  614.             HideDItem(dptr, TermNameStatText);
  615.             HideDItem(dptr, TermName);
  616.             }
  617.         }
  618.     else {
  619.         TermPrefsHdl = GetDefaultTerminal();
  620.         IsNewPrefRecord = TRUE;
  621.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWTERM);
  622.         }
  623.  
  624.     HLock((Handle) TermPrefsHdl);
  625.     TermPrefsPtr = *TermPrefsHdl;
  626.     SetTEText(dptr, TermName, PrefRecordNamePtr);
  627.     SetCntrl(dptr, TermANSI, TermPrefsPtr->ANSIgraphics);
  628.     HideDItem(dptr, TermANSI);                // Perhaps later
  629.     SetCntrl(dptr, TermXterm, TermPrefsPtr->Xtermsequences);
  630.     SetCntrl(dptr, Termvtwrap, TermPrefsPtr->vtwrap);
  631.     SetCntrl(dptr, Termmeta, TermPrefsPtr->emacsmetakey);
  632.     SetCntrl(dptr, Termarrow, TermPrefsPtr->emacsarrows);
  633.     SetCntrl(dptr, TermMAT, TermPrefsPtr->MATmappings);
  634.     SetCntrl(dptr, Termeightbit, TermPrefsPtr->eightbit);
  635.     SetCntrl(dptr, Termclearsave, TermPrefsPtr->clearsave);
  636.     SetCntrl(dptr, TermVT100, (TermPrefsPtr->vtemulation == 0));
  637.     SetCntrl(dptr, TermVT220, (TermPrefsPtr->vtemulation == 1));
  638.     scratchlong = (long)(TermPrefsPtr->vtwidth);
  639.     NumToString(scratchlong, scratchPstring);
  640.     SetTEText(dptr, TermWidth, scratchPstring);
  641.     scratchlong = (short)(TermPrefsPtr->vtheight);
  642.     NumToString(scratchlong, scratchPstring);
  643.     SetTEText(dptr, TermHeight, scratchPstring);
  644.     scratchlong = TermPrefsPtr->fontsize;
  645.     NumToString(scratchlong, scratchPstring);
  646.     SetTEText(dptr, TermFontSize, scratchPstring);
  647.     scratchlong = TermPrefsPtr->numbkscroll;
  648.     NumToString(scratchlong, scratchPstring);
  649.     SetTEText(dptr, TermScrollback, scratchPstring);
  650.     SetTEText(dptr, TermAnswerback, TermPrefsPtr->AnswerBackMessage);
  651.     
  652.     for(scratchshort = CountMItems(TPopup[0].h); scratchshort; scratchshort--) {
  653.         GetItem(TPopup[0].h, scratchshort, scratchPstring);
  654.         if (EqualString(scratchPstring, (TermPrefsPtr->DisplayFont), TRUE, FALSE))
  655.             TPopup[0].choice = scratchshort;
  656.         }
  657.     
  658.     ZeroNumOnly();
  659.     NumOnly[0] = TermSafeItem;
  660.     NumOnly[1] = TermWidth; NumOnly[2] = TermHeight; NumOnly[3] = TermFontSize;
  661.     NumOnly[4] = TermScrollback;  NumOnly[5] = 0;
  662.     
  663.     if (theWorld.hasColorQD) {
  664.         for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) {
  665.             BoxColorItems[scratchshort] = TermNFcolor + scratchshort;
  666.             BlockMove(&(TermPrefsPtr->nfcolor) + scratchshort,
  667.                 &BoxColorData[scratchshort], sizeof(RGBColor));
  668.             UItemAssign( dptr, TermNFcolor + scratchshort, ColorBoxItemProcUPP);
  669.             }
  670.         }
  671.     else
  672.         NumberOfColorBoxes = 0;        // B&W machine
  673.         
  674.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  675.     ColorBoxPoint.v = 0;            // screen
  676.         
  677.     SelIText(dptr, TermName, 0, 32767);
  678.     ShowWindow(dptr);
  679.     
  680.     while (ditem > 2) {
  681.         ModalDialog(TerminalModalProcUPP, &ditem);
  682.         switch (ditem) {
  683.             case    TermANSI:
  684.             case    TermXterm:
  685.             case    Termvtwrap:
  686.             case    Termmeta:
  687.             case    Termarrow:
  688.             case    TermMAT:
  689.             case    Termeightbit:
  690.             case    Termclearsave:
  691.                 FlipCheckBox(dptr, ditem);
  692.                 break;
  693.             
  694.             case    TermVT100:
  695.                 SetCntrl(dptr, TermVT100, 1);
  696.                 SetCntrl(dptr, TermVT220, 0);
  697.                 SetTEText(dptr, TermAnswerback, "\pVT100");
  698.                 break;
  699.  
  700.             case    TermVT220:
  701.                 SetCntrl(dptr, TermVT100, 0);
  702.                 SetCntrl(dptr, TermVT220, 1);
  703.                 SetTEText(dptr, TermAnswerback, "\pVT220");
  704.                 break;
  705.             
  706.             case    TermNFcolor:    
  707.             case    TermNBcolor:    
  708.             case    TermBFcolor:    
  709.             case    TermBBcolor:    
  710.                 if (theWorld.hasColorQD) {
  711.                     UserLikesNewColor = GetColor(ColorBoxPoint, "\pPlease Select New Color",
  712.                          &BoxColorData[ditem-TermNFcolor], &scratchRGBcolor);
  713.                     if (UserLikesNewColor)
  714.                         BoxColorData[ditem-TermNFcolor] = scratchRGBcolor;
  715.                     }
  716.                 break;
  717.                 
  718.             default:
  719.                 break;
  720.             
  721.             } // switch
  722.         } // while
  723.             
  724.     GetItem(TPopup[0].h, TPopup[0].choice, scratchPstring);
  725.     PopupCleanup();
  726.     
  727.     if (ditem == 2) {
  728.         if (IsNewPrefRecord) DisposeHandle((Handle) TermPrefsHdl);
  729.         else ReleaseResource((Handle) TermPrefsHdl);
  730.         
  731.         DisposeDialog(dptr);
  732.         return(FALSE);            // No changes should be made.
  733.         }
  734.     
  735.         
  736.     if (theWorld.hasColorQD) {
  737.         for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) {
  738.                 BlockMove(&BoxColorData[scratchshort], 
  739.                     &(TermPrefsPtr->nfcolor) + scratchshort, sizeof(RGBColor));
  740.             }
  741.         }
  742.         
  743.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  744.     BlockMove(scratchPstring, (TermPrefsPtr->DisplayFont), scratchPstring[0]+1);
  745.     
  746.     TermPrefsPtr->ANSIgraphics = GetCntlVal(dptr, TermANSI);
  747.     TermPrefsPtr->Xtermsequences = GetCntlVal(dptr, TermXterm);
  748.     TermPrefsPtr->vtwrap = GetCntlVal(dptr, Termvtwrap);
  749.     TermPrefsPtr->emacsmetakey = GetCntlVal(dptr, Termmeta);
  750.     TermPrefsPtr->emacsarrows = GetCntlVal(dptr, Termarrow);
  751.     TermPrefsPtr->MATmappings = GetCntlVal(dptr, TermMAT);
  752.     TermPrefsPtr->eightbit = GetCntlVal(dptr, Termeightbit);
  753.     TermPrefsPtr->clearsave = GetCntlVal(dptr, Termclearsave);
  754.     
  755.     TermPrefsPtr->vtemulation = (GetCntlVal(dptr, TermVT220) != 0);
  756.  
  757.     GetTEText(dptr, TermWidth, scratchPstring);
  758.     StringToNum(scratchPstring, &scratchlong);
  759.     BoundsCheck(&scratchlong, 133, 10);
  760.     TermPrefsPtr->vtwidth = (short) scratchlong;
  761.     
  762.     GetTEText(dptr, TermHeight, scratchPstring);
  763.     StringToNum(scratchPstring, &scratchlong);
  764.     BoundsCheck(&scratchlong, 80, 10);
  765.     TermPrefsPtr->vtheight = (short) scratchlong;
  766.  
  767.     GetTEText(dptr, TermFontSize, scratchPstring);
  768.     StringToNum(scratchPstring, &scratchlong);
  769.     BoundsCheck(&scratchlong, 24, 4);
  770.     TermPrefsPtr->fontsize = (short) scratchlong;
  771.  
  772.     GetTEText(dptr, TermScrollback, scratchPstring);
  773.     StringToNum(scratchPstring, &scratchlong);
  774.     BoundsCheck(&scratchlong, 50000, 24);
  775.     TermPrefsPtr->numbkscroll = (short) scratchlong;
  776.  
  777.     GetTEText(dptr, TermAnswerback, scratchPstring);
  778.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  779.     BlockMove(scratchPstring, TermPrefsPtr->AnswerBackMessage, scratchPstring[0]+1);
  780.     
  781.     GetTEText(dptr, TermName, PrefRecordNamePtr);
  782.     
  783.     if (IsNewPrefRecord) {
  784.         UseResFile(TelInfo->SettingsFile);
  785.         resourceID = UniqueID(TERMINALPREFS_RESTYPE);
  786.         AddResource((Handle)TermPrefsHdl, TERMINALPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  787.         UpdateResFile(TelInfo->SettingsFile);
  788.         ReleaseResource((Handle)TermPrefsHdl);
  789.         }
  790.     else {
  791.         UseResFile(TelInfo->SettingsFile);
  792.         GetResInfo((Handle)TermPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  793.         SetResInfo((Handle)TermPrefsHdl, resourceID, PrefRecordNamePtr);
  794.         ChangedResource((Handle)TermPrefsHdl);
  795.         UpdateResFile(TelInfo->SettingsFile);
  796.         ReleaseResource((Handle)TermPrefsHdl);
  797.         }
  798.     
  799.     DisposeDialog(dptr);
  800.     return(TRUE);            // A resource has changed or been added.    
  801. }
  802.  
  803. Boolean EditSession(StringPtr PrefRecordNamePtr)
  804. {
  805.     DialogPtr        dptr;
  806.     short            ditem, scratchshort, resourceID;
  807.     long            scratchlong;
  808.     ResType            scratchResType;
  809.     Boolean            IsNewPrefRecord;
  810.     SessionPrefs**    SessPrefsHdl;
  811.     SessionPrefs*    SessPrefsPtr;
  812.     Str255            scratchPstring, scratchPstring2;
  813.     popup SPopup[] = {{SessTermPopup, (MenuHandle) 0, 1},
  814.                         {SessTransTablePopup, (MenuHandle) 0, 1},
  815.                         {0, (MenuHandle) 0, 0}};
  816.  
  817.     dptr = GetNewMySmallStrangeDialog(SessionConfigDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  818.     ditem = 3;
  819.         
  820.     SPopup[0].h = NewMenu(666, "\p");
  821.     UseResFile(TelInfo->SettingsFile);
  822.     AddResMenu(SPopup[0].h, TERMINALPREFS_RESTYPE);
  823.     EnableItem(SPopup[0].h, 0);        // Make sure the entire menu is enabled
  824.     
  825.     SPopup[1].h = NewMenu(667, "\p");
  826.     AppendMenu(SPopup[1].h, "\pNone");
  827.     AddResMenu(SPopup[1].h, USER_TRSL);
  828.     EnableItem(SPopup[1].h, 0);        // Make sure the entire menu is enabled
  829.  
  830.     PopupInit(dptr, SPopup);
  831.     
  832.     if (PrefRecordNamePtr[0] != 0) {
  833.         IsNewPrefRecord = FALSE;
  834.         UseResFile(TelInfo->SettingsFile);
  835.         SessPrefsHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, PrefRecordNamePtr);
  836.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  837.             HideDItem(dptr, SessAlias);
  838.             HideDItem(dptr, SessAliasStatText);
  839.             }
  840.         }
  841.     else {
  842.         SessPrefsHdl = GetDefaultSession();
  843.         IsNewPrefRecord = TRUE;
  844.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION);
  845.         }
  846.         
  847.     HLock((Handle) SessPrefsHdl);
  848.     SessPrefsPtr = *SessPrefsHdl;
  849.     SetCntrl(dptr, SessTEKinhib, (SessPrefsPtr->tektype == -1));
  850.     SetCntrl(dptr, SessTEK4014, (SessPrefsPtr->tektype == 0));
  851.     SetCntrl(dptr, SessTEK4105, (SessPrefsPtr->tektype == 1));
  852.     SetCntrl(dptr, SessPasteQuick, (SessPrefsPtr->pastemethod == 0));
  853.     SetCntrl(dptr, SessPasteBlock, (SessPrefsPtr->pastemethod == 1));
  854.     SetCntrl(dptr, SessDeleteDel, (SessPrefsPtr->bksp == 1));
  855.     SetCntrl(dptr, SessDeleteBS, (SessPrefsPtr->bksp == 0));
  856.     SetCntrl(dptr, SessForceSave, SessPrefsPtr->forcesave);
  857.     SetCntrl(dptr, SessBezerkeley, SessPrefsPtr->crmap);
  858.     SetCntrl(dptr, SessLinemode, SessPrefsPtr->linemode);
  859.     SetCntrl(dptr, SessTEKclear, SessPrefsPtr->tekclear);
  860.     SetCntrl(dptr, SessHalfDuplex, SessPrefsPtr->halfdup);
  861.     SetCntrl(dptr, SessLowLevelErrs, SessPrefsPtr->showlowlevelerrors);
  862.     SetCntrl(dptr, SessAuthenticate, SessPrefsPtr->authenticate);
  863.     SetCntrl(dptr, SessEncrypt, SessPrefsPtr->encrypt);
  864.     SetCntrl(dptr, SessLocalEcho, SessPrefsPtr->localecho);
  865.     SetTEText(dptr, SessHostName, SessPrefsPtr->hostname);
  866.     SetTEText(dptr, SessAlias, PrefRecordNamePtr);
  867.     NumToString(SessPrefsPtr->port, scratchPstring);
  868.     SetTEText(dptr, SessPort, scratchPstring);
  869.     NumToString(SessPrefsPtr->pasteblocksize, scratchPstring);
  870.     SetTEText(dptr, SessBlockSize, scratchPstring);
  871.     scratchPstring[0] = 2;
  872.     scratchPstring[1] = '^';
  873.     if (SessPrefsPtr->ckey != -1) {
  874.         scratchPstring[2] = SessPrefsPtr->ckey ^ 64;
  875.         SetTEText(dptr, SessInterrupt, scratchPstring);
  876.         }
  877.     if (SessPrefsPtr->skey != -1) {
  878.         scratchPstring[2] = SessPrefsPtr->skey ^ 64;
  879.         SetTEText(dptr, SessSuspend, scratchPstring);
  880.         }
  881.     if (SessPrefsPtr->qkey != -1) {
  882.         scratchPstring[2] = SessPrefsPtr->qkey ^ 64;
  883.         SetTEText(dptr, SessResume, scratchPstring);
  884.         }
  885.     for(scratchshort = CountMItems(SPopup[0].h); scratchshort; scratchshort--) {
  886.         GetItem(SPopup[0].h, scratchshort, scratchPstring);
  887.         if (EqualString(scratchPstring, (SessPrefsPtr->TerminalEmulation), TRUE, FALSE))
  888.             SPopup[0].choice = scratchshort;
  889.         }
  890.     for(scratchshort = CountMItems(SPopup[1].h); scratchshort; scratchshort--) {
  891.         GetItem(SPopup[1].h, scratchshort, scratchPstring);
  892.         if (EqualString(scratchPstring, (SessPrefsPtr->TranslationTable), TRUE, FALSE))
  893.             SPopup[1].choice = scratchshort;
  894.         }
  895.     
  896.     NumberOfColorBoxes = 0;
  897.     ZeroNumOnly();
  898.     NumOnly[0] = SessSafeItem;
  899.     NumOnly[1] = SessPort;  NumOnly[2] = SessBlockSize;
  900.     
  901.     SelIText(dptr, SessAlias, 0, 32767);
  902.     ShowWindow(dptr);
  903.     
  904.     while (ditem > 2) {
  905.         ModalDialog(SessionModalProcUPP, &ditem);
  906.         switch (ditem) {
  907.             case    SessForceSave:
  908.             case    SessBezerkeley:
  909.             case    SessLinemode:
  910.             case    SessTEKclear:
  911.             case    SessHalfDuplex:
  912.             case    SessLowLevelErrs:
  913.             case    SessAuthenticate:
  914.             case    SessEncrypt:
  915.             case    SessLocalEcho:
  916.                 FlipCheckBox(dptr, ditem);
  917.                 break;
  918.             
  919.             case    SessTEKinhib:
  920.                 SetCntrl(dptr, SessTEKinhib, 1);
  921.                 SetCntrl(dptr, SessTEK4014, 0);
  922.                 SetCntrl(dptr, SessTEK4105, 0);
  923.                 break;
  924.             case    SessTEK4014:
  925.                 SetCntrl(dptr, SessTEKinhib, 0);
  926.                 SetCntrl(dptr, SessTEK4014, 1);
  927.                 SetCntrl(dptr, SessTEK4105, 0);
  928.                 break;
  929.             case    SessTEK4105:
  930.                 SetCntrl(dptr, SessTEKinhib, 0);
  931.                 SetCntrl(dptr, SessTEK4014, 0);
  932.                 SetCntrl(dptr, SessTEK4105, 1);
  933.                 break;
  934.                 
  935.             case    SessPasteQuick:
  936.                 SetCntrl(dptr, SessPasteQuick, 1);
  937.                 SetCntrl(dptr, SessPasteBlock, 0);
  938.                 break;
  939.  
  940.             case    SessPasteBlock:
  941.                 SetCntrl(dptr, SessPasteQuick, 0);
  942.                 SetCntrl(dptr, SessPasteBlock, 1);
  943.                 break;
  944.  
  945.             case    SessDeleteDel:
  946.                 SetCntrl(dptr, SessDeleteDel, 1);
  947.                 SetCntrl(dptr, SessDeleteBS, 0);
  948.                 break;
  949.  
  950.             case    SessDeleteBS:
  951.                 SetCntrl(dptr, SessDeleteDel, 0);
  952.                 SetCntrl(dptr, SessDeleteBS, 1);
  953.                 break;
  954.  
  955.             case    SessInterrupt:
  956.             case    SessSuspend:
  957.             case    SessResume:
  958.                 GetTEText(dptr, ditem, scratchPstring);
  959.                 if ((scratchPstring[1] < 32) && (scratchPstring[1] > 0)) {
  960.                     scratchPstring[0] = 2;
  961.                     scratchPstring[2] = scratchPstring[1] ^ 64;
  962.                     scratchPstring[1] = '^';
  963.                     SetTEText(dptr, ditem, scratchPstring);
  964.                     }
  965.                 break;
  966.                 
  967.             default:
  968.                 break;
  969.             
  970.             } // switch
  971.         } // while
  972.         
  973.     GetItem(SPopup[0].h, SPopup[0].choice, scratchPstring);
  974.     GetItem(SPopup[1].h, SPopup[1].choice, scratchPstring2);
  975.     PopupCleanup();
  976.  
  977.     if (ditem == 2) {
  978.         if (IsNewPrefRecord) DisposeHandle((Handle) SessPrefsHdl);
  979.         else ReleaseResource((Handle) SessPrefsHdl);
  980.         
  981.         DisposeDialog(dptr);
  982.         return(FALSE);            // No changes should be made.
  983.         }
  984.         
  985.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  986.     BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1);
  987.  
  988.     if (Length(scratchPstring2) > 63) scratchPstring[0] = 63;
  989.     BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1);
  990.  
  991.     SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105);
  992.     SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick);
  993.     SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel);
  994.     SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave);
  995.     SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley);
  996.     SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode);
  997.     SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear);
  998.     SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex);
  999.     SessPrefsPtr->showlowlevelerrors = GetCntlVal(dptr, SessLowLevelErrs);
  1000.     SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate);
  1001.     SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt);
  1002.     SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho);
  1003.  
  1004.     GetTEText(dptr, SessPort, scratchPstring);
  1005.     StringToNum(scratchPstring, &scratchlong);
  1006.     BoundsCheck(&scratchlong, 65530, 1);
  1007.     SessPrefsPtr->port = (short) scratchlong;
  1008.  
  1009.     GetTEText(dptr, SessBlockSize, scratchPstring);
  1010.     StringToNum(scratchPstring, &scratchlong);
  1011.     BoundsCheck(&scratchlong, 4097, 100);
  1012.     SessPrefsPtr->pasteblocksize = (short) scratchlong;
  1013.  
  1014.     GetTEText(dptr, SessHostName, scratchPstring);
  1015.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1016.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1017.     
  1018.     GetTEText(dptr, SessHostName, scratchPstring);
  1019.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1020.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1021.  
  1022.     GetTEText(dptr, SessAlias, PrefRecordNamePtr);
  1023.  
  1024.     GetTEText(dptr, SessInterrupt, scratchPstring);
  1025.     if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64;
  1026.     else SessPrefsPtr->ckey = -1;
  1027.     
  1028.     GetTEText(dptr, SessSuspend, scratchPstring);
  1029.     if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64;
  1030.     else SessPrefsPtr->skey = -1;
  1031.     
  1032.     GetTEText(dptr, SessResume, scratchPstring);
  1033.     if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64;
  1034.     else SessPrefsPtr->qkey = -1;
  1035.     
  1036.     if (IsNewPrefRecord) {
  1037.         UseResFile(TelInfo->SettingsFile);
  1038.         resourceID = UniqueID(SESSIONPREFS_RESTYPE);
  1039.         AddResource((Handle)SessPrefsHdl, SESSIONPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  1040.         UpdateResFile(TelInfo->SettingsFile);
  1041.         ReleaseResource((Handle)SessPrefsHdl);
  1042.         }
  1043.     else {
  1044.         UseResFile(TelInfo->SettingsFile);
  1045.         GetResInfo((Handle)SessPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1046.         SetResInfo((Handle)SessPrefsHdl, resourceID, PrefRecordNamePtr);
  1047.         ChangedResource((Handle)SessPrefsHdl);
  1048.         UpdateResFile(TelInfo->SettingsFile);
  1049.         ReleaseResource((Handle)SessPrefsHdl);
  1050.         }
  1051.     
  1052.     DisposeDialog(dptr);
  1053.     return(TRUE);            // A resource has changed or been added.    
  1054. }
  1055.  
  1056. Boolean EditFTPUser(StringPtr PrefRecordNamePtr)
  1057. {
  1058.     DialogPtr    dptr;
  1059.     short        ditem, scratchshort, resourceID, vRefNum;
  1060.     ResType        scratchResType;
  1061.     Boolean        IsNewPrefRecord;
  1062.     FTPUser**    FTPUHdl;
  1063.     FTPUser*    FTPUptr;
  1064.     Str255        scratchPstring, scratchPstring2;
  1065.  
  1066.     dptr = GetNewMySmallStrangeDialog(FTPUserDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  1067.     ditem = 3;
  1068.  
  1069.     HideDItem(dptr, FTPUcanchangeCWD);        // Sometime later, perhaps
  1070.         
  1071.     if (PrefRecordNamePtr[0] != 0) {
  1072.         IsNewPrefRecord = FALSE;
  1073.         UseResFile(TelInfo->SettingsFile);
  1074.         FTPUHdl = (FTPUser **)Get1NamedResource(FTPUSER, PrefRecordNamePtr);
  1075.         HLock((Handle) FTPUHdl);
  1076.         FTPUptr = *FTPUHdl;
  1077.         SetCntrl(dptr, FTPUcanchangeCWD, FTPUptr->UserCanCWD);
  1078.         SetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1079.         for (scratchshort = 8, scratchPstring[0] = 8; scratchshort > 0; scratchshort--)
  1080.             scratchPstring[scratchshort] = 'Ñ';
  1081.          SetTEText(dptr, FTPUpassword, scratchPstring);
  1082.         vRefNum = VolumeNameToRefNum(FTPUptr->DefaultDirVolName);
  1083.         }
  1084.     else {
  1085.         IsNewPrefRecord = TRUE;
  1086.         FTPUHdl = (FTPUser **)NewHandleClear(sizeof(FTPUser));
  1087.         HLock((Handle) FTPUHdl);
  1088.         FTPUptr = *FTPUHdl;
  1089.         vRefNum = -1;                        // Default Volume
  1090.         FTPUptr->DefaultDirDirID = 2;        // Root directory
  1091.         SetCntrl(dptr, FTPUcanchangeCWD, 0);
  1092.         }
  1093.  
  1094.     PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1095.     SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1096.     
  1097.     SelIText(dptr, FTPUusername, 0, 32767);
  1098.     ShowWindow(dptr);
  1099.     
  1100.     while (ditem > 2) {
  1101.         ModalDialog(DLOGwOK_CancelUPP, &ditem);
  1102.         switch (ditem) {
  1103.             case    FTPUcanchangeCWD:
  1104.                 FlipCheckBox(dptr, ditem);
  1105.                 break;
  1106.             
  1107.             case    FTPUDfltDirButton:
  1108.                 SelectDirectory(&vRefNum, &(FTPUptr->DefaultDirDirID));
  1109.                 PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1110.                 SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1111.                 break;
  1112.                 
  1113.             default:
  1114.                 break;
  1115.             
  1116.             } // switch
  1117.         } // while
  1118.         
  1119.     if (ditem == 2) {
  1120.         if (IsNewPrefRecord) DisposeHandle((Handle) FTPUHdl);
  1121.         else ReleaseResource((Handle) FTPUHdl);
  1122.         
  1123.         DisposeDialog(dptr);
  1124.         return(FALSE);            // No changes should be made.
  1125.         }
  1126.         
  1127.     FTPUptr->UserCanCWD = GetCntlVal(dptr, FTPUcanchangeCWD);
  1128.     GetDirectoryName(vRefNum, 2, FTPUptr->DefaultDirVolName);
  1129.     
  1130.     GetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1131.     GetTEText(dptr, FTPUpassword, scratchPstring);
  1132.     
  1133.     if (scratchPstring[0] != 'Ñ') {
  1134.         // Encrypt the new (or possibly modified) password.
  1135.         PtoCstr(scratchPstring);
  1136.         Sencompass((char *)scratchPstring, (char *)scratchPstring2);
  1137.         CtoPstr((char *)scratchPstring2);
  1138.         BlockMove(scratchPstring2, FTPUptr->EncryptedPassword, Length(scratchPstring2)+1);
  1139.         }
  1140.             
  1141.     if (IsNewPrefRecord) {
  1142.         UseResFile(TelInfo->SettingsFile);
  1143.         resourceID = UniqueID(FTPUSER);
  1144.         AddResource((Handle)FTPUHdl, FTPUSER, resourceID, PrefRecordNamePtr);
  1145.         UpdateResFile(TelInfo->SettingsFile);
  1146.         ReleaseResource((Handle)FTPUHdl);
  1147.         }
  1148.     else {
  1149.         UseResFile(TelInfo->SettingsFile);
  1150.         GetResInfo((Handle)FTPUHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1151.         SetResInfo((Handle)FTPUHdl, resourceID, PrefRecordNamePtr);
  1152.         ChangedResource((Handle)FTPUHdl);
  1153.         UpdateResFile(TelInfo->SettingsFile);
  1154.         ReleaseResource((Handle)FTPUHdl);
  1155.         }
  1156.     
  1157.     DisposeDialog(dptr);
  1158.     return(TRUE);            // A resource has changed or been added.    
  1159. }
  1160.